#include "IEmitter.h"
#include "ParticleFlyweight.h"
#include "../SGD Wrappers/CSGD_TextureManager.h"
#include "../../Source/Tokens/BaseToken.h"


IEmitter::IEmitter(void)
{
	m_bActive = false;
	m_bIsLooping = false;
	m_fSpawnTimer = 0.0f;
	TokenToTrack(nullptr);
}


IEmitter::~IEmitter(void)
{
	delete m_pFLW;
}

void IEmitter::Update( float fElapsedTime )
{
	if(m_bActive)
	{
		if(TokenToTrack() != nullptr)
		{
			PosX(TokenToTrack()->GetPosX());
			PosY(TokenToTrack()->GetPosY());
		}

		if((int)LiveParticles().size()/* + (int)DeadParticles().size()*/ < m_nMaxParticles)
		{
			m_fSpawnTimer += m_fSpawnRate*fElapsedTime;
			if( m_fSpawnTimer >= 1.0f)
			{
				int spawnNum = int(m_fSpawnTimer);
				SpawnParticles(spawnNum, PosX(),PosX()+Width(),PosY(),PosY()+Height());
				m_fSpawnTimer = 0.0f;
			}
		}


		//update every particle
		for(auto i = m_LiveParticles.begin(); i != m_LiveParticles.end(); /*++i*/)
		{
			i->Update(fElapsedTime);

			//remove from updates if dead
			if(i->IsDead() == true)
			{
				m_DeadParticles.push_back(*i);
				i = m_LiveParticles.erase(i);
			}
			else
				++i;
		}
	}
}
void IEmitter::Render()
{
	if(m_bForward)
	for(auto i = m_LiveParticles.begin(); i != m_LiveParticles.end(); i++)
	{
		i->Render();
	}
	else if(m_bForward == false)
	for(auto i = m_LiveParticles.rbegin(); i != m_LiveParticles.rend(); i++)
	{
		i->Render();
	}
}


void IEmitter::SpawnParticles(int maxParticles,
							  float minPosX, float maxPosX, float minPosY, float maxPosY)
{
	if( maxParticles > 0)
		for(int i = 0; i <= maxParticles; ++i)
		{
			//float Life =(float)(rand()%((int)m_pFLW->MaxLife() - (int)m_pFLW->MinLife())+(int)m_pFLW->MinLife());
			float Life = CalcLifetime();
			float posX, posY;

			CalcEmitRange( minPosX, maxPosX, minPosY, maxPosY, posX, posY);

			if(m_DeadParticles.size() == 0)
			{
				m_LiveParticles.push_back(CParticle(Life, posX, posY,m_pFLW));
			}
			else if(m_DeadParticles.size() > 0 && m_bIsLooping == true)
			{
				CParticle temp = *(m_DeadParticles.begin());
				m_DeadParticles.pop_front();
				temp.InitializeParticle(Life, posX, posY,m_pFLW);
				m_LiveParticles.push_back(temp);
			}
		}

}

void IEmitter::Name(const char* val)
{
	m_szName = val;
}

void IEmitter::StartEmission()
{
	m_bActive = true;
}
void IEmitter::EndEmission()
{
	m_bActive = false;
}

void IEmitter::CalcEmitRange(float& minPosX, float& maxPosX, float& minPosY, float& maxPosY, float& endX, float& endY)
 {
	 endX =(float)(rand()%((int)maxPosX - (int)minPosX)+(int)minPosX);
	 endY =(float)(rand()%((int)maxPosY - (int)minPosY)+(int)minPosY);
 }
float IEmitter::CalcLifetime(/*float MinLife, float MaxLife*/)
{
	float minlife = m_pFLW->MinLife();
	float maxlife = m_pFLW->MaxLife();
	

	int low = (int)(minlife  * 10000);
	int high = (int)(maxlife * 10000);
	

	int L = (rand()%(high - low))+low;
	float life = L/10000.0f;
	//float life = (float)(rand()%((int)m_pFLW->MaxLife() - (int)m_pFLW->MinLife())+(int)m_pFLW->MinLife());
return life; 
}